package cn.tedu.reflection;

import javax.naming.Name;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//测试 反射的高级方法
public class Test4 {
    public static void main(String[] args) throws Exception {
//        method();//反射创建对象
        method2();//反射操作属性
//        method3();//反射操作方法
    }
    //反射操作方法
    private static void method3() throws Exception {
        //1.获取Class对象
        Class c=Person.class;
        //2.利用反射执行方法
        Method m=c.getMethod("show",int.class);
        // Object invoke(Object obj, Object... args) --Object obj是要执行那个对象的方法 -- Object... args调用方法是要传入的具体参数是什么？
        Object obj=c.newInstance();
        m.invoke(obj,10);//执行方法
    }

    //反射操作属性
    public static void method2() throws Exception {
        //1.获取Class对象
        Class c = Person.class;
        //2.利用反射set/get
        Field f = c.getField("name");
        f = null;//NullPointerException --空指针异常
        //解决方法：加if判断，判断不为空才执行代码
        if (f != null) {//判断不为空才执行代码
            //set(1,2) --1要给那个对象设置值--2时要设置的具体的值是什么？
            Object obj = c.newInstance();
            f.set(obj, "jack");//给属性设置值
            //get（1）--1是要获取那个对象的值
            System.out.println(f.get(obj));
        }
    }

    //反射创建对象--newInstance()
    public static void method() throws Exception {
        //1.获取class对象
        Class c=Person.class;
        //2.利用反射new--newInstance()
        Object o=c.newInstance();//会调用无参构造的方法
        System.out.println(o);//cn.tedu.reflection.Person@1b6d3586
        //获取要调用  含参 构造方法
       Constructor con=c.getConstructor(String.class);//--参数是含参构造需要的参数类型的class对象
        //con.newInstance();参数是要触发含参构造时，想要具体指定的参数值，是Constructor类提供的newInstance(Object... initargs) 方法
        Object o1=con.newInstance("jack");
        System.out.println(o1);
        //调用Person的资源 --show方法和test方法
        Person P= (Person) o1;//向下转型，就是用子类的功能
        P.show(10);
        P.test();
    }
}
